﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using UnityEngine.SceneManagement;
public class a: AsyncOperation
{
    
}


public abstract class AsyncOperationEx
{
    public virtual bool isDone
    {
        get;
    }

    public virtual Object asset
    {
        get;
    }

    public virtual bool allowSceneActivation
    {
        get;
        set;
    }

    public virtual float progress
    {
        get;
    }
}

public class LoadSceneAsyncOperation: AsyncOperationEx
{
    string levelName;
    UnityEngine.SceneManagement.LoadSceneMode mode;
    int priority;
    IEnumerator e;
    AsyncOperation sceneOperation;

    public LoadSceneAsyncOperation(string levelName, UnityEngine.SceneManagement.LoadSceneMode mode, int priority)
    {
        this.levelName = levelName;
        this.mode = mode;
        this.priority = priority;

        e = Execute();
    }

    IEnumerator Execute()
    {
        AsyncOperationEx operation = NewBundleManager.instance.PrepareForLoadSceneAsync(levelName, priority);
        if (operation != null)
        {
            while (!operation.isDone)
            {
                yield return null;
            }
        }

        sceneOperation = SceneManager.LoadSceneAsync(levelName, mode);
        while (!sceneOperation.isDone)
        {
            yield return null;
        }
    }

    public override bool isDone
    {
        get
        {
            return !e.MoveNext();
        }
    }

    public override Object asset
    {
        get
        {
            return null;
        }
    }

    public override bool allowSceneActivation
    {
        get
        {
            if (sceneOperation != null)
            {
                return sceneOperation.allowSceneActivation;
            }
            return false;
        }

        set
        {
            if (sceneOperation != null)
            {
                sceneOperation.allowSceneActivation = value;
            }
        }
    }

    public override float progress
    {
        get
        {
            if (sceneOperation != null)
            {
                return sceneOperation.progress;
            }
            return 0;
        }
    }
}

public static class SplitAlphaType
{
	public const byte NONE = 0;
	public const byte SPLIT_TEX = 1;
	public const byte HORIZONTAL = 2;
	public const byte VERTICAL = 3;
}

public class SpriteSheetInfo
{
	//for create sprite sheet
	public bool heuristic_mask;
	public byte edge_extrude;
	public bool is_from_interface;
	public int alpha_threshold;
	public bool multi_pack;
	public int max_size;
	public float scale;

	//for run
	public byte split_alpha_type;
	public bool is_sub_pack;
	public string[] dirs;
	public string[] sub_pack_names;
	private SpriteSheetInfo[] sub_pack_infos;

	public float getScale()
	{
		if(scale < 0.001)
		{
			return 1;
		}
		return scale;
	}

	public bool isLeaf()
	{
		return sub_pack_names == null || sub_pack_names.Length <= 0;
	}

	public bool isRoot()
	{
		return !is_sub_pack;
	}

	public void setSubPackInfo(SpriteSheetInfo[] infos)
	{
		sub_pack_infos = infos;
	}

	public void Write(BinaryWriter writer)
	{
		writer.Write(scale);
		writer.Write(split_alpha_type);
		//for sub pack
		writer.Write(is_sub_pack);
		int packLen = 0;
		if(sub_pack_names != null)
		{
			packLen = sub_pack_names.Length;
		}
		
		writer.Write(packLen);
		if(sub_pack_names != null)
		{
			for(int i = 0; i < sub_pack_names.Length; i++)
			{
				writer.Write(sub_pack_names[i]);
			}
		}

		if(!is_sub_pack)
		{
			int len = dirs.Length;
			writer.Write(len);
			for(int i = 0; i < dirs.Length; i++)
			{
				writer.Write(dirs[i]);
			}
		}
	}
	
	public void Read(BinaryReader reader)
	{
		scale = reader.ReadSingle();
		split_alpha_type = reader.ReadByte();
		//for sub pack
		is_sub_pack = reader.ReadBoolean();
		int packLen = reader.ReadInt32();
		if(packLen > 0)
		{
			sub_pack_names = new string[packLen];
			for(int i = 0; i < packLen; i++)
			{
				sub_pack_names[i] = reader.ReadString();
			}
		}

		if(!is_sub_pack)
		{
			int len = reader.ReadInt32();
			dirs = new string[len];
			for(int i = 0; i < len; i++)
			{
				dirs[i] = reader.ReadString();
			}
		}
	}

	public List<string> getFiles(string resPath, string ext, bool deleteResPath = false)
	{
		List<string> ret = new List<string>();
		for(int i = 0; i < dirs.Length; i++)
		{
			string dir = resPath + "/" + dirs[i];
			if(Directory.Exists(dir))
			{
				string[] files = Directory.GetFiles(dir, "*" + ext, SearchOption.AllDirectories);
				if(files.Length > 0)
				{
					for(int j = 0; j < files.Length; j++)
					{
						ret.Add(files[j]);
					}
				}
			}
			else
			{
				string file = dir + ext;
				if(File.Exists(file))
				{
					ret.Add(file);
				}
			}
		}

		if(deleteResPath)
		{
			for(int i = 0; i < ret.Count; i++)
			{
				int index = ret[i].LastIndexOf(ext);
				ret[i] = ret[i].Remove(index);
				ret[i] = ret[i].Remove(0, resPath.Length + 1);
			}
		}
		return ret;
	}

	public bool hasFiles(string resPath, string ext)
	{
		for(int i = 0; i < dirs.Length; i++)
		{
			string dir = resPath + "/" + dirs[i];
			if(Directory.Exists(dir))
			{
				string[] files = Directory.GetFiles(dir, "*" + ext, SearchOption.AllDirectories);
				if(files.Length > 0)
				{
					return true;
				}
			}
			else
			{
				string file = dir + ext;
				if(File.Exists(file))
				{
					return true;
				}
			}
		}
		return false;
	}

	public bool isJpg(string resPath)
	{
		return hasFiles(resPath, ".jpg");
	}

	public bool isPng(string resPath)
	{
		return hasFiles(resPath, ".png");
	}
}

public class SpriteSheetConfig : Dictionary<string, SpriteSheetInfo>
{
	public void Write(BinaryWriter writer)
	{
		int len = this.Count;
		writer.Write(len);
		SortedDictionary<string, SpriteSheetInfo> temp = new SortedDictionary<string, SpriteSheetInfo>(this);
		SortedDictionary<string, SpriteSheetInfo>.Enumerator enumerator = temp.GetEnumerator();
		while(enumerator.MoveNext())
		{
			writer.Write(enumerator.Current.Key);
			enumerator.Current.Value.Write(writer);
		}
	}

	public void Read(BinaryReader reader)
	{
		int len = reader.ReadInt32();
		for(int i = 0; i < len; i++)
		{
			string key = reader.ReadString();
			SpriteSheetInfo info = new SpriteSheetInfo();
			info.Read(reader);
			this.Add(key, info);
		}
	}

	public void getSpriteSheetGroup(string name, ref Dictionary<string, SpriteSheetInfo> ret)
	{
		SpriteSheetInfo info = null;
		if(this.TryGetValue(name, out info))
		{
			ret.Add(name, info);
			if(info.sub_pack_names != null)
			{
				for(int i = 0; i < info.sub_pack_names.Length; i++)
				{
					getSpriteSheetGroup(info.sub_pack_names[i], ref ret);
				}
			}
		}
	}

	public void initSubPacks()
	{
		Enumerator e = this.GetEnumerator();
		while(e.MoveNext())
		{
			string[] packNames = e.Current.Value.sub_pack_names;
			if(packNames != null && packNames.Length > 0)
			{
				List<SpriteSheetInfo> subPackInfos = new List<SpriteSheetInfo>();
				for(int i = 0; i < packNames.Length; i++)
				{
					SpriteSheetInfo temp = null;
					this.TryGetValue(packNames[i], out temp);
					subPackInfos.Add(temp);
				}

				e.Current.Value.setSubPackInfo(subPackInfos.ToArray());
			}
		}
	}

	public HashSet<string> getSpriteSheetNames(string path)
	{
		HashSet<string> spriteSheetPaths = new HashSet<string>();
		SpriteSheetConfig.Enumerator enumerator = this.GetEnumerator();
		while(enumerator.MoveNext())
		{
			string spriteSheetName = enumerator.Current.Key;
			string[] dirs = enumerator.Current.Value.dirs;
			for(int i = 0; i < dirs.Length; i++)
			{
				string tempDir = dirs[i];
				if(tempDir == path || tempDir.StartsWith(path + "/"))
				{
					spriteSheetPaths.Add(spriteSheetName);
				}
				else if(path.StartsWith(tempDir))
				{
					spriteSheetPaths.Add(spriteSheetName);
				}
			}
		}
		return spriteSheetPaths;
	}
	
	public string getSpriteSheetName(string path, bool isRoot = false)
	{
		SpriteSheetConfig.Enumerator enumerator = this.GetEnumerator();
		while(enumerator.MoveNext())
		{
			if(!isRoot && !enumerator.Current.Value.isLeaf())
			{
				continue;
			}
			else if(isRoot && enumerator.Current.Value.is_sub_pack)
			{
				continue;
			}

			string spriteSheetName = enumerator.Current.Key;
			string[] dirs = enumerator.Current.Value.dirs;
			for(int i = 0; i < dirs.Length; i++)
			{
				string tempDir = dirs[i];
				if(path.StartsWith(tempDir))
				{
					bool canReturn = false;
					if(path.Length == tempDir.Length)
					{
						canReturn = true;
					}
					else if(path.Length > tempDir.Length)
					{
                        if (tempDir[tempDir.Length - 1] == '/')
                        {
                            if (path[tempDir.Length - 1] == '/' || path[tempDir.Length - 1] == '.')
                            {
                                canReturn = true;
                            }
                        }
						else if(path[tempDir.Length] == '/' || path[tempDir.Length] == '.')
						{
							canReturn = true;
						}
					}

					if(canReturn)
					{
						return spriteSheetName;
					}
				}
			}
		}
		return null;
	}

    public void DeleteSpriteSheet(string spriteSheetName)
    {
        SpriteSheetInfo spInfo = null;
        if (this.TryGetValue(spriteSheetName, out spInfo))
        {
            this.Remove(spriteSheetName);

            if(spInfo.sub_pack_names != null)
            {
                for (int i = 0; i < spInfo.sub_pack_names.Length; i++)
                {
                    DeleteSpriteSheet(spInfo.sub_pack_names[i]);
                }
            }
        }
    }
}

public class ResSpriteSheetInfo
{
	public string name;
	public Dictionary<string, SpriteSheetLoader> spriteSheetLoaderMap = new Dictionary<string, SpriteSheetLoader>();
	public Dictionary<string, string> dirSpriteSheetMap = null;
	public HashSet<string> spriteSheetSet = new HashSet<string>();
	public SpriteSheetConfig config;

	public void init()
	{
//		TextAsset text = ResourcesEx.LoadText(ResourcesEx.SpriteSheetConfigName, true, name, true);
//		if(text != null)
//		{
//			dirSpriteSheetMap = new Dictionary<string, string>();
//			
//			byte[] bytes = text.bytes;
//			MemoryStream stream = new MemoryStream(bytes);
//			BinaryReader reader = new BinaryReader(stream);
//			config = new SpriteSheetConfig();
//			config.Read(reader);
//			config.initSubPacks();
//
//			SpriteSheetConfig.Enumerator enumerator2 = config.GetEnumerator();
//			while(enumerator2.MoveNext())
//			{
//				spriteSheetSet.Add(enumerator2.Current.Key);
//
//				if(enumerator2.Current.Value.is_sub_pack)
//				{
//					continue;
//				}
//
//				string[] dirs2 = enumerator2.Current.Value.dirs;
//				for(int i = 0; i < dirs2.Length; i++)
//				{
//					try
//					{
//						dirSpriteSheetMap.Add(dirs2[i], enumerator2.Current.Key);
//					}
//					catch(System.Exception e)
//					{
//						string temp = null;
//						dirSpriteSheetMap.TryGetValue(dirs2[i], out temp);
//						//if(UnityEngine.Debug.enableLog)UnityEngine.Debug.LogError("add dir failed: " + dirs2[i] + " " + enumerator2.Current.Key + " " + temp);
//						//if(UnityEngine.Debug.enableLog)UnityEngine.Debug.LogException(e);
//					}
//				}
//			}
//		}
//		else
//		{
//            if (name.Equals("RawUI") || name.Equals("LocalRes"))
//            {
////                if (UnityEngine.Debug.enableLog) UnityEngine.Debug.Log("load text failed:" + ResourcesEx.SpriteSheetConfigName + " " + name);
//            }
//            else
//            {
////                if (UnityEngine.Debug.enableLog) UnityEngine.Debug.LogError("load text failed:" + ResourcesEx.SpriteSheetConfigName + " " + name);
//            }
//			
//		}
	}
}

public delegate void AsyncCallBack<T>(T o) where T : class;

public static class ResourcesEx
{
    public const string BundleResDir = "Assets/BundleRes";
    public const string SpriteAtlasDir = "sprite_atlas";
    public const string ResDir = "Assets/Resources";
	public const string SpriteSheetTexSuffix = "";
	public const string SpriteSheetAlphaSuffix = "_alpha";
	public const string AnimDirName = "built_anim";
	public const string CopiedDirName = "copied_res";
	public const string IcpResDirName = "icp_res";
	public const string spriteSheetMaterialSuffix = "_sprite";
	public const string spriteSheetUiMaterialSuffix = "_ui";
	public const string spriteSheetConfigSuffix = "_config";
	public const string ImageFontConfigName = "image_font_config";


    public const char dirSymbol = '+';
    public const string SheetDirName = "sprite_sheet";
    public const string SpriteSheetConfigName = "sprite_sheet_config";
    static string spriteToSheetMapConfigName = "sprite_sheet_map";
    static SpriteToSheetMap spriteToSheetMap = null;
    static Dictionary<string, SpriteSheetLoaderEx> spriteSheetLoadExMap = new Dictionary<string, SpriteSheetLoaderEx>();
    static bool inited;
    static bool enableSpriteSheet;

	public static string getSheetDirName()
	{
		return PlatformEx.getPlatform().ToString() + "/" + SheetDirName;
	}

    public static void EnableSpriteSheet(bool v)
    {
        if(enableSpriteSheet != v)
        {
            enableSpriteSheet = v;

            Reset();
        }
    }

    static bool isEnableSpriteSheet()
    {
        return enableSpriteSheet;
    }

	public static void initSpriteSheetConfig()
	{
        if (!isEnableSpriteSheet())
        {
            return;
        }

        if(inited)
        {
            return;
        }

        inited = true;

        if (spriteToSheetMap == null || spriteToSheetMap.Count <= 0)
        {
            string mapPath = PlatformEx.getPlatform().ToString() + "/" + spriteToSheetMapConfigName;
            TextAsset config = ResourceManager.LoadAsset<TextAsset>(mapPath);
            if(config != null)
            {
                spriteToSheetMap = SpriteToSheetMap.CreateFromBinary(config.bytes);
            }
        }
	}

	public static void Reset()
	{
        inited = false;
        if (spriteToSheetMap != null)
        {
            spriteToSheetMap.Clear();
            spriteToSheetMap = null;
        }

        spriteSheetLoadExMap.Clear();
	}

    static SpriteSheetLoaderEx GetSpriteSheetLoaderEx(string path)
    {
        SpriteSheetLoaderEx loader = null;
        if (!spriteSheetLoadExMap.TryGetValue(path, out loader))
        {
            loader = new SpriteSheetLoaderEx(path);
            spriteSheetLoadExMap.Add(path, loader);
        }
        return loader;
    }

	public static Sprite LoadSprite(string spritePath)
	{
        return null;
	}

	public static SpriteEx LoadSpriteEx(string spritePath, bool useMultiLang = true)
    {
		if (string.IsNullOrEmpty(spritePath))
        {
            return null;
        }

		SpriteEx resultSprite = null;
		if (useMultiLang)
		{
			string langSpritePath = LangManager.GetResourcePath(spritePath);
			if (langSpritePath != spritePath)
			{
				resultSprite = RealLoadSpriteEx(langSpritePath);
				if (resultSprite != null)
				{
					return resultSprite;
				}
			}
		}

        return RealLoadSpriteEx(spritePath);
    }

    public static void LoadSpriteExAsync(string spritePath, int priority, System.Action<SpriteEx> callBack)
	{
		string langSpritePath = LangManager.GetResourcePath(spritePath);
		if (langSpritePath != spritePath)
		{
            RealLoadSpriteExAsync(langSpritePath, priority, (resultSprite) =>
				{
					if(resultSprite != null)
					{
						if(callBack != null)
						{
							callBack(resultSprite);
						}
						return;
					}
                    RealLoadSpriteExAsync(spritePath, priority, callBack);
				});
		}
		else
		{
            RealLoadSpriteExAsync(spritePath, priority, callBack);
		}
    }

    private static SpriteEx RealLoadSpriteEx(string spritePath)
    {
        if (spritePath == null)
        {
            return null;
        }

        if(isEnableSpriteSheet())
        {
            initSpriteSheetConfig();
        }

        if(spriteToSheetMap != null)
        {
            string sheetPath = null;
            if (spriteToSheetMap.TryGetValue(spritePath, out sheetPath))
            {
                SpriteSheetLoaderEx helper = GetSpriteSheetLoaderEx(sheetPath);
                if (helper != null)
                {
                    SpriteEx sprite = helper.Load(spritePath);
                    if (sprite != null)
                    {
                        return sprite;
                    }
                }
            }
        }


        Sprite sprite2 = null;
        if(sprite2 == null)
        {
            sprite2 = Load<Sprite>(spritePath);
        }

        if(sprite2 == null)
        {
            if(spritePath.IndexOf('/') >= 0)
            {
                string spritePath2 = Path.GetDirectoryName(spritePath);
                string spriteName = Path.GetFileName(spritePath);

                Texture tex = Load<Texture2D>(spritePath2);
                if(tex != null)
                {
                    Sprite[] objs = LoadAll<Sprite>(spritePath2);
                    for(int i = 0; i < objs.Length; i++)
                    {
                        Sprite sprite3 = objs[i] as Sprite;
                        if(sprite3.name == spriteName)
                        {
                            sprite2 = sprite3;
                            break;
                        }
                    }
                }
            }
        }


		if (sprite2 == null)
		{
			return null;
		}

        SpriteEx spriteEx = new SpriteEx();
        spriteEx.sprite = sprite2;
        return spriteEx;
    }


    private static void RealLoadSpriteExAsync(string spritePath, int priority, System.Action<SpriteEx> callBack)
    {
        if (string.IsNullOrEmpty(spritePath))
        {
            callBack(null);
            return;
        }

        if(isEnableSpriteSheet())
        {
            initSpriteSheetConfig();
        }

        if(spriteToSheetMap != null)
        {
            string sheetPath = null;
            if (spriteToSheetMap.TryGetValue(spritePath, out sheetPath))
            {
                SpriteSheetLoaderEx helper = GetSpriteSheetLoaderEx(sheetPath);
                if (helper != null)
                {
                    helper.LoadAsync(spritePath, (sprite) =>
                        {
                            if (sprite != null)
                            {
                                callBack(sprite);
                                return;
                            }

                            RealLoadSpriteExAsync2(spritePath, priority, callBack);
                        });
                }
                else
                {
                    RealLoadSpriteExAsync2(spritePath, priority, callBack);
                }
            }
            else
            {
                RealLoadSpriteExAsync2(spritePath, priority, callBack);
            }
        }
        else
        {
            RealLoadSpriteExAsync2 (spritePath, priority, callBack);
        }
    }

    static void RealLoadSpriteExAsync2 (string spritePath, int priority, System.Action<SpriteEx> callBack)
    {
        MyEventObject.instance.StartCoroutine(AsyncLoader(spritePath, typeof(Sprite), priority, (sprite) =>
            {
                if(sprite == null)
                {
                    if (spritePath.IndexOf ('/') >= 0)
                    {
                        string spritePath2 = Path.GetDirectoryName (spritePath);
                        string spriteName = Path.GetFileName (spritePath);
                        Texture tex = Load<Texture2D> (spritePath2);
                        if (tex != null)
                        {
                            Sprite[] objs = LoadAll<Sprite> (spritePath2);
                            for (int i = 0; i < objs.Length; i++)
                            {
                                Sprite sprite3 = objs [i] as Sprite;
                                if (sprite3.name == spriteName)
                                {
                                    sprite = sprite3;
                                    break;
                                }
                            }
                        }
                    }
                }

                if(sprite == null)
                {
                    callBack(null);
                }
                else
                {
                    SpriteEx spriteEx = new SpriteEx();
                    spriteEx.sprite = sprite as Sprite;
                    callBack(spriteEx);
                }
            }));
    }

	public static bool isFromSpriteSheet(this Sprite sprite)
	{
		Texture2D tex = sprite.texture;
		if(sprite.rect.width == tex.width && sprite.rect.height == tex.height && sprite.name == tex.name)
		{
			return false;
		}
		return true;
	}

	public static SpriteInfo GetSpriteInfo(this Sprite sprite)
	{
        return null;

//		if(sprite == null)
//		{
//			return new SpriteInfo();
//		}
//
//		Texture2D tex = sprite.texture;
//		if(!sprite.isFromSpriteSheet())
//		{
//			return new SpriteInfo();
//		}
//		
//		initSpriteSheetConfig();
//
//		ResSpriteSheetInfo info = null;
//		for(int i = 0; i < dirs.Length; i++)
//		{
//			if(dirs[i].spriteSheetSet.Contains(tex.name))
//			{
//				info = dirs[i];
//				break;
//			}
//		}
//
//		SpriteSheetLoaderEx loader = getSpriteSheetLoaderEx(info, tex.name);
//		if(loader == null)
//		{
//			return new SpriteInfo();
//		}
//		
//		return loader.GetSpriteInfo(sprite.name);
	}

    public static void LoadScene(string levelName)
    {
        LoadScene(levelName, LoadSceneMode.Single);
    }

    public static void LoadScene(string levelName, UnityEngine.SceneManagement.LoadSceneMode mode)
	{
        NewBundleManager.instance.PrepareForLoadScene(levelName);
        SceneManager.LoadScene(levelName, mode);
	}

    public static AsyncOperationEx LoadSceneAsync(string levelName, int priority)
    {
        return LoadSceneAsync(levelName, LoadSceneMode.Single, priority);
    }



    public static AsyncOperationEx LoadSceneAsync(string levelName, UnityEngine.SceneManagement.LoadSceneMode mode, int priority)
	{
        LoadSceneAsyncOperation operation = new LoadSceneAsyncOperation(levelName, mode, priority);
        return operation;
	}

    static Object Load(string path, System.Type t)
    {
        if (t == null)
        {
            return Resources.Load(path);
        }
        else
        {
            return Resources.Load(path, t);
        }
    }

	static T Load<T>(string path) where T: UnityEngine.Object
	{
        return Resources.Load<T>(path);
    }

    static ResourceRequest LoadAsync(string path, System.Type t)
    {
        if (t == null)
        {
            return Resources.LoadAsync(path);
        }
        else
        {
            return Resources.LoadAsync(path, t);
        }
    }

    static ResourceRequest LoadAsync<T>(string path) where T: UnityEngine.Object
    {
        return Resources.LoadAsync<T>(path);
    }


	static T[] LoadAll<T>(string path) where T: UnityEngine.Object
	{
        T[] t = Resources.LoadAll<T>(path);
        if(t != null && t.Length > 0)
        {
          return t;
        }

		return null;
	}


    public static Shader LoadShader(string shaderName)
    {
        Shader shader = NewBundleManager.instance.LoadShader(shaderName);
        if (shader == null)
        {
            shader = Shader.Find(shaderName);
        }
        return shader;
    }

    public static T LoadAsset<T>(string path) where T: UnityEngine.Object
    {
        return LoadAsset(path, typeof(T)) as T;
    }

    public static Object LoadAsset(string path)
    {
        return LoadAsset(path, null);
    }

    public static Object LoadAsset(string path, System.Type t)
    {
        if (path == null)
        {
            return null;
        }

        Object obj = NewBundleManager.instance.LoadAsset(path, t);
        if(obj == null)
        {
            obj = Load(path, t);
        }
        return obj;
    }

    public static void LoadAssetAsync<T>(string path, int priority, AsyncCallBack<Object> callBack)
    {
        LoadAssetAsync(path, typeof(T), priority, callBack);
    }

    public static void LoadAssetAsync(string path, int priority, AsyncCallBack<Object> callBack)
    {
        LoadAssetAsync(path, null, priority, callBack);
    }

    public static void LoadAssetAsync(string path, System.Type t, int priority, AsyncCallBack<Object> callBack)
	{
        RealLoadAssetAsync(path, t, priority, callBack);
	}

    private static void RealLoadAssetAsync(string path, System.Type t, int priority, AsyncCallBack<Object> callBack)
	{
		if (path == null)
		{
			if(callBack != null)
			{
				callBack(null);
			}
			return;
		}

        MyEventObject.instance.StartCoroutine(AsyncLoader(path, t, priority, callBack));
	}

    private static IEnumerator AsyncLoader(string path, System.Type t, int priority, AsyncCallBack<Object> callBack)
    {
        string resPath = LangManager.GetResourcePath(path);

        IEnumerator e = s(resPath, t, priority);
        while (e.MoveNext())
        {
            if (e.Current is Object)
            {
                break;
            }
            yield return null;
        }
        Object asset = e.Current as Object;

        if (asset == null)
        {
            IEnumerator e2 = s(path, t, priority);
            while (e2.MoveNext())
            {
                if (e2.Current is Object)
                {
                    break;
                }
                yield return null;
            }
            asset = e2.Current as Object;
        }

        if (callBack != null)
        {
            callBack(asset);
        }
    }

    private static IEnumerator s(string path, System.Type t, int priority)
    {
        Object result = null;
        AsyncOperationEx request = NewBundleManager.instance.LoadAssetAsync(path, t, priority);
        if(request != null)
        {
            while(!request.isDone)
            {
                yield return null;
            }

            result = request.asset;
        }

        if(result == null)
        {
            ResourceRequest request2 = LoadAsync(path, t);
            request2.priority = priority;

            if(request2 != null)
            {
                while(!request2.isDone)
                {
                    yield return new WaitForEndOfFrame();
                }

                result = request2.asset;
            }
        }

        if (result != null)
        {
            yield return result;
        }
    }
}

